Content starts here Mutator Function Examples
This page last changed on Apr 01, 2008.

edocs Home > BEA AquaLogic Data Services Platform 3.0/3.2 Documentation > ALDSP 3.2 New Features Documentation

Mutator Function Examples

This topic provides several examples showing how to use the built-in mutator functions to perform common update operations.

Update Based on Simple Parameters

This example shows a data service update operation that accepts two simple input parameters, the customer ID (cid) and the Social Security Number (ssn).

declare procedure tns:update($cid as xs:string, $ssn as xs:string) {
   declare $c as element(customer) := getCustomerByCustID($cid);
   declare $cc as changed-element(customer) := fn-bea:changed-element($c);
   set $cc := fn-bea:replace-value($cc, "ssn", $ssn);
   tns:updateCUSTOMER($cc);
}

The update() operation retrieves the customer data by invoking the getCustomerByCustID() operation and updates the Social Security Number based on the ssn parameter. The example then updates the data source by calling the updateCUSTOMER() data service operation.

Update Based on Complex Input Parameters

This example shows a data service update operation that accepts complex input parameters.

The example uses the following input parameters:

p_customer Parameter 

<p_customer>
   <customer_id>1</customer_id>
   <ssn>545-54-5445</ssn>
</p_customer >

p_address Parameter

<p_address>
   <address_id>1</address_id>
   <street1>1108 Delmas Ave</street1>
   <street2></street2>
   <address_type>HOME</address_type>
</p_address>

The getCustomerByCustID() operation returns the following data:

getCustomerByCustID() Return Data

<customer>
   <customer_id>1</customer_id>
   <first_name>John</first_name>
   <last_name>Deer</last_name>
   <ssn>123-12-1234</ssn>
   <address>
      <address_id>1</address_id>
      <customer_id>1</customer_id>
      <city>San Jose</city>
      <street1>123 Main Street</street1>
      <street2>Apt 808</street2>
      <address_type>HOME</address_type>
   </address>
</customer>

Example - Replacing Values Based on Complex Input Parameters

The following example retrieves the customer data by invoking the getCustomerByCustID() operation, and returns the data in a hierarchical shape with a top-level node and multiple child nodes. The example then updates the Social Security Number (ssn) element using data supplied through the first parameter and updates the street element based on data in the second parameter.

Finally, the example updates the data source by calling the updateCUSTOMER() data service operation.

declare procedure tns:update($p1 as element(p_customer),
                             $p2 as element(p_address)) {
   declare $c as element(customer) := getCustomerByCustID($p1/customer_id);
   declare $cc as changed-element(customer) := fn-bea:changed-element($c);

   set $cc := fn-bea:replace-value($cc, "ssn", fn:data($p1/ssn));

   iterate $a at $i over $c/address {
      if ($a/address_type eq $p2/address_type) {
         declare $path1 as xs:string := concat("address[", $i, "]/street1");
         declare $path2 as xs:string := concat("address[", $i, "]/street2");
         set $cc := fn-bea:replace-value($cc, $path1, data($p2/street1));
         set $cc := fn-bea:replace-value($cc, $path2, data($p2/street2));
      }
   }

   tns:updateCustomer($cc);
}

Example - Inserting a New Element Based on Complex Input Parameters

The following example retrieves the customer data by invoking the getCustomerByCustID() operation, and returns the data in a hierarchical shape with a top-level node and multiple child nodes. The example then declares a new address element, populates the fields, and uses the insert-into() built-in function to insert the address into the customer element.

Finally, the example updates the data source by calling the updateCUSTOMER() data service operation.

declare procedure tns:update($p1 as element(p_customer),
                             $p2 as element(p_address)) {
   declare $c as element(customer) := getCustomerByCustID($p1/customer_id);
   declare $cc as changed-element(customer) := fn-bea:changed-element($c);

   declare $addr as element(AddressType):=
      <address>
         <address_id>{data($p2/address_id)}</address_id>
         <customer_id>{data($p1/customer_id}</customer_id>
         <city>{data($p2/city)}</city>
         <street1>{data($p2/street1)}</street1>
         <street2>{data($p2/street1)}</street2>
         <address_type>{data($p2/address_type)}</address_type>
      </address>

   set $cc := fn-bea:insert-into($cc, ".", $addr);

   (: this call updates Customer and inserts new Address :)
   tns:updateCustomer($cc);
}

Update When the Parameter Structure Matches the Return Type

This example shows a data service update operation that accepts a complex parameter as input, where the parameter structure matches the return type defined for the given data service.

The example uses the following input parameter:

p_customer Parameter

<p_customer>
   <customer_id>1</customer_id>
   <ssn>545-54-5445</ssn>
   <address>
      <address_id>1</address_id>
      <city>San Jose</city>
      <street1>1108 Delmas Ave</street1>
      <street2></street2>
      <address_type>HOME</address_type>
   </address>
   <address>
      <address_id>2</address_id>
      <city>San Jose</city>
      <street1>1108 First St.</street1>
      <street2></street2>
      <address_type>WORK</address_type>
   </address>
</p_customer>

The getCustomerByCustID() operation returns the following data:

getCustomerByCustID() Return Data

<customer>
   <customer_id>1</customer_id>
   <first_name>John</first_name>
   <last_name>Smith</last_name>
   <ssn>123-12-1234</ssn>
   <address>
      <address_id>1</address_id>
      <customer_id>1</customer_id>
      <city>Santa Clara</city>
      <street1>350 El Camino Real</street1>
      <street2>Test Street</street2>
      <address_type>HOME</address_type>
   </address>
</customer>

Example - Replacing all Values in a Complex Element

The following example invokes the updateCustomer() operation in the data service to replace all values in the underlying data source (the update is performed based on the primary key). This is possible because the structure of the input parameter matches the return type defined for the data service.

Note that the example includes a helper procedure that replaces the value of each child element of $ce with the value of the corresponding child element (using the same name) in $va.
declare procedure tns:replace-values($ce as changed-element(),
                                     $path as xs:string,
                                     $va as element()) as changed-element() {
   declare $parent as changed-element() := $ce;
   declare $child as element() := fn-bea:current-value($ce);

   (: manual navigation according to $path :)
   iterate $step over tokenize($path, "/|[") {
      if (starts-with($step, "[") {
         (: this is a filter (assuming positional), so just shave :)
         (: the square brackets off and apply the same filter :)
         set $index as xs:string := substring($step, 2, string-length($step) - 2);
         set $child := $child[xs:integer($index)]
      } else {
         set $child := $child/[local-name() eq $step]
      }
   }

   iterate $leaf over $child/* {
      declare $vaChild as element() := $va/*[local-name() eq local-name($leaf)];
      if (exists($vaChild)) {
         declare $cpath = concat($path, "/", local-name($leaf));
         set $parent := fn-bea:replace-value($parent, $cpath, data($vaChild));
      }
   }

   return value $parent;
}

declare procedure tns:update($p1 as element(p_customer)) {
   declare $cust as element(customer) := getCustomerByCustID($p1/customer_id);
   declare $ucust as changed-element(customer) := fn-bea:changed-element($cust);

   iterate $addr at $i over $p1/address {
      declare $uaddr as element(AddressType) :=
         <address>
            <address_id>{ data($addr/address_id) }</address_id>
            <customer_id>{ data($addr/customer_id) }</customer_id>
            <city>{ data($addr/city) }</city>
            <street1>{ data($addr/street1) }</street1>
            <street2>{ data($addr/street1) }</street2>
            <address_type>{ data($addr/address_type) }</address_type>
         </address>
      if (exists($cust/address[$i])) {
         declare $path as xs:string := concat("address[", $i , "]");
         set $ucust := tns:replace-values($ucust, $path, $uaddr);
      } else {
         set $ucust := fn-bea:insert-into($ucust, ".", $uaddr);
      }
   }

   tns:updateCustomer($uCustomer);
}

Update Based on Differences Between Old and New Values

These examples show how to perform an update operation based on two complex parameters, one containing old values and the other containing potentially new values.

The example uses the following input parameters:

customer Parameter (New Values)

<customer>
   <customer_id>1</customer_id>
   <first_name>John</first_name>
   <last_name>Smith</last_name>
   <ssn>345-43-4988</ssn>
</customer>

customer Parameter (Old Values)

<customer>
   <customer_id>1</customer_id>
   <first_name>Johnny</first_name>
   <last_name>Smithline</last_name>
   <ssn>345-43-4988</ssn>
</customer>

Example - Updating Based on Parameter Differences Determined Through a Series of if Statements

The following example compares the two input parameters (the first containing old values and the second containing potentially new values) for differences using a series of if statements. The example then calls the updateCustomer() operation in the data service to update the data in the underlying data source if changes have been identified.

declare procedure tns:update($p_old as element(customer),
                             $p_new as element(customer)) {
   declare $cust as changed-element(customer) := fn-bea:changed-element($p_old);
   declare $modified as xs:boolean := false();

   if (data($p_old/customer_id) eq data($p_new/customer_id) ) then {
      if (data($p_old/first_name) ne data($p_new/first_name)) then {
         set $cust := fn-bea:replace-value($cust, "first_name", fn:data($p_new/first_name));
         set $modified := true();
      } else {}
      if (data($p_old/last_name) ne data($p_new/last_name)) then {
         set $cust := fn-bea:replace-value($cust, "last_name", fn:data($p_new/last_name));
         set $modified := true();
      } else {}
      if (data($p_old/ssn) ne data($p_new/ssn)) then {
         set $cust := fn-bea:replace-value($cust, "ssn", fn:data($p_new/ssn));
         set $modified := true();
      } else {}
      if ($modified) then {
         tns:updatecustomer($c);
      } else {}
   } else {}
}

Example - Updating Based on Parameter Differences Determined Through Iteration

The following example compares the two input parameters for differences by iterating through the elements, and then calls the updateCustomer() operation in the data service to update the data in the underlying data source if changes have been identified.

declare procedure tns:update($p_old as element(customer),
                             $p_new as element(customer)) {
   declare $cust as changed-element(customer) := fn-bea:changed-element($p_old);
   declare $modified as xs:boolean := false();

   if (data($p_old/customer_id) eq data($p_new/customer_id) ) then {
      iterate $child over $p_old/* {
         declare $name as xs:string := local-name($child);
         declare $new := data($p_new/*[local-name() eq $name]);
         if (data($child) ne $new) {
            set $cust := fn-bea:replace-value($cust, $name, $new);
            set $modified := true();
         }
      }
      if ($modified) then {
         tns:updatecustomer($c);
      }
   }
}

Update Using Additional Data

This example shows how to perform additional function calls to enrich the data before performing an update operation.

The following input parameter is used:

p_customer Parameter

<p_customer>
   <customer_id>1</customer_id>
   <ssn>545-54-5445</ssn>
   <address>
      <address_id>1</address_id>
      <city>San Jose</city>
      <street1>1108 First St.</street1>
      <street2></street2>
      <country>US</country>
   </address>
</p_customer>

The getCustomerByCustID() operation returns the following data:

getCustomerByCustID() Return Data

<customer>
   <customer_id>1</customer_id>
   <first_name>John</first_name>
   <last_name>Deer</last_name>
   <ssn>123-12-1234</ssn>
   <address>
      <address_id>1</address_id>
      <customer_id>1</customer_id>
      <city>San Jose</city>
      <street1>1108 First</street1>
      <street2></street2>
      <zip_code>95125</zip_code>
      <address_valid>N</address_valid>
      <country>US</country>
   </address>
</customer>

The getValidAddress() operation accepts address information as a parameter and returns a standardized address element together with a validity code indicating whether the address is valid or not. The getValidAddress() operation returns the following data:

getValidAddress() Return Data

<address>
   <city>San Jose</city>
   <street1>1108 1st Street</street1>
   <street2></street2>
   <zip_code>95131</zip_code>
   <address_valid>Y</address_valid>
   <country>US</country>
</address>

Example - Retrieving Additional Data Before Updating

The following example calls a read operation in the data service to retrieve additional information to include in the updated information. The example then replaces the appropriate values and calls the updateCustomer() operation to update the data in the underlying data source.

declare procedure tns:update($p1 as element(p_customer)) {
   declare $c as element(customer) := getCustomerByCustID($p1/customer_id, p1/address_id);
   declare $cc as changed-element(customer) := fn-bea:changed-element($c);

   set $cc := fn-bea:replace-value($cc, "ssn", $p1/ssn);

   declare $vAddress as element(ValidAddress) := tns:getValidAddress(
      <ns1:address>
         <city>{ data($p1/city) }</city>
         <street1>{ data($p1/street1) }</street1>
         <street2>{ data($p1/stree2) }</street2>
         <country>{ data($p1/country) }</country>
      </ns1:address>);

   set $cc := fn-bea:replace-value($cc, "city", $vAddress/city)
   set $cc := fn-bea:replace-value($cc, "street1", $vAddress/street1)
   set $cc := fn-bea:replace-value($cc, "street2", $vAddress/street2)
   set $cc := fn-bea:replace-value($cc, "zip_code", $vAddress/zip_code)
   set $cc := fn-bea:replace-value($cc, "address_valid", $vAddress/address_valid)
   set $cc := fn-bea:replace-value($cc, "country", $vAddress/country)

   tns:updateCustomer($cc);
}

Update Operation Replication

This example shows how to send changed data to two different data sources.

The following input parameter is used:

p_customer Parameter

<p_customer>
   <customer_id>1</customer_id>
   <ssn>545-54-5445</ssn>
   <first_name>Johan</first_name>
   <last_name>Tyson</last_name>
   <cud_operation>U</cud_operation>
   <address>
      <address_id>1</address_id>
      <city>San Jose</city>
      <street1>1108 First St.</street1>
      <street2></street2>
      <country>US</country>
      <cud_operation>U</cud _operation>
   </address>
   <address>
      <address_id>1</address_id>
      <city>San Jose</city>
      <street1>1108 First St.</street1>
      <street2></street2>
      <country>US</country>
      <cud_operation>D</cud _operation>
   </address>
</p_customer>

Example - Updating Multiple Data Sources

The following example reads and updates customer information, replacing the data in the first data source and inserting the customer data in the second data source. Similarly, the example reads and updates the related address information, replacing the data in the first data source and inserting the address data in the second data source.

declare procedure tns:update($p1 as element(p_customer)) {
   declare $c as element(customer) := getCustomerInfoByCustID(data($p1/customer_id));
   declare $cc as changed-element(customer) := fn-bea:changed-element($c);
   declare $curc as element(customer);

   if (data($p1/cud_operation) eq "U") then {
      set $cc := fn-bea:replace-value($cc, "first_name", data($p1/first_name));
      set $cc := fn-bea:replace-value($cc, "last_name", data($p1/last_name));
      set $cc := fn-bea:replace-value($cc, "ssn", data($p1/ssn));

      updateCustomer($cc); (: this update goes into the first data source :)

      set $curc := fn-bea:current-value($cc);
      insertCustomer($curc); (: this insert goes into the second data source :)
   }

   {
      declare $addr as element(address) := getAddressInfoByCustID(data($p1/customer_id));
      declare $caddr as changed-element(address) := fn-bea:changed-element($addr);
      declare $curaddr as element(address);
      declare $paddr := $p1/address[1];

      if (data($p1/cud_operation) eq "U") then {
         set $caddr := fn-bea:replace-value($caddr, "city", data($paddr/city));
         set $caddr := fn-bea:replace-value($caddr, "street1", data($paddr/street1));
         set $caddr := fn-bea:replace-value($caddr, "street2", data($paddr/street2));
         set $caddr := fn-bea:replace-value($caddr, "country", data($paddr/country));

         updateAddress($caddr); (: this update goes into the first data source :)

         set $curaddr :=
            <address>
               <address_id>{ data($paddr/address_id) }</address_id>
               <city>{ data($paddr/city) }</city>
               <street1>{ data($paddr/street1) }</street1>
               <street2>{ data($paddr/street2) }</street2>
               <country>{ data($paddr/country) }</country>
            </address>

         insertAddress($curaddr); (:this insert goes into the second data source :)
      }
   }
}

See Also

Concepts
How Tos
Reference
Document generated by Confluence on Apr 28, 2008 16:19